package com.shuaiche.yeguan.util;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.UUID;


/**
 * 图片工具
 */
public class BitmapUtil {


    /***
     * 图片按比例大小压缩方法（根据路径获取图片并压缩）
     *
     * @param srcPath
     * @return
     * @see [类、类#方法、类#成员]
     */
    public static Bitmap getimage(String srcPath) {
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        //开始读入图片，此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);//此时返回bm为空

        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        //现在主流手机比较多是800*480分辨率，所以高和宽我们设置为
        float hh = 800f;//这里设置高度为800f
        float ww = 480f;//这里设置宽度为480f
        //缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
        int be = 1;//be=1表示不缩放
        if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0)
            be = 1;
        newOpts.inSampleSize = be;//设置缩放比例
        //重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
        bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
        return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
    }

    public static int[] getImageWidthAndHeight(String srcPath) {
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        //开始读入图片，此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(srcPath, newOpts);
        return new int[]{newOpts.outWidth, newOpts.outHeight};
    }


    /***
     * 质量压缩
     *
     * @param image
     * @return
     * @see [类、类#方法、类#成员]
     */
    public static Bitmap compressImage(Bitmap image) {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(CompressFormat.JPEG, 100, baos);//质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        int options = 100;
        while (baos.toByteArray().length / 1024 > 100) {    //循环判断如果压缩后图片是否大于100kb,大于继续压缩
            baos.reset();//重置baos即清空baos
            image.compress(CompressFormat.JPEG, options, baos);//这里压缩options%，把压缩后的数据存放到baos中
            options -= 10;//每次都减少10
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
        return bitmap;
    }

    public static byte[] getCompressIamgeData(String pathName) {
        int maxWidth = Math.min(DeviceHelper.getScreenWidthPx(), 1080);
        int maxHeight = Math.min(DeviceHelper.getScreenHeightPx(), 1920);
        Bitmap image = getScaledBitmap(pathName, maxWidth, maxHeight);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int options = 70;
        image.compress(CompressFormat.JPEG, options, baos);

        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        // 开始读入图片，此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        // 现在主流手机比较多是800*480分辨率，所以高和宽我们设置为
        // float hh = 800f;// 这里设置高度为800f
        // float ww = 480f;// 这里设置宽度为480f
        float hh = 1600;
        float ww = 1600;
        // 缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
        int be = 1;// be=1表示不缩放
        if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) { // 如果高度高的话根据高度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0)
            be = 1;
        newOpts.inSampleSize = be; // 设置缩放比例
        // newOpts.inPreferredConfig = Config.RGB_565;//降低图片从ARGB888到RGB565
        // 重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
        isBm = new ByteArrayInputStream(baos.toByteArray());
        bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);

        return Bitmap2Bytes(bitmap);
//        return baos.toByteArray();
    }


    public static byte[] compressImageToMaxEdge(String imagePath, int maxEdge) {
        BitmapFactory.Options options = new BitmapFactory.Options();

        // 1. 获取原始图片尺寸
        options.inJustDecodeBounds = true; // 仅读取边界信息[2,4](@ref)
        BitmapFactory.decodeFile(imagePath, options);
        int originalWidth = options.outWidth;
        int originalHeight = options.outHeight;

        // 2. 计算初始缩放比例（inSampleSize）
        int inSampleSize = 1;
        if (originalWidth > maxEdge || originalHeight > maxEdge) {
            // 计算宽高缩放比例，取较大值[2,3](@ref)
            float scale = Math.max(originalWidth / (float) maxEdge, originalHeight / (float) maxEdge);
            inSampleSize = (int) Math.ceil(scale); // 向上取整，确保缩放后尺寸不超过目标[2,5](@ref)
        }

        // 3. 加载初步缩放的Bitmap
        options.inJustDecodeBounds = false;
        options.inSampleSize = inSampleSize; // 设置采样率[1,2](@ref)
        Bitmap bitmap = BitmapFactory.decodeFile(imagePath, options);
        if (bitmap == null) return null; // 文件读取失败处理

        // 4. 二次精确缩放（解决inSampleSize整数倍误差）
        int currentMaxEdge = Math.max(bitmap.getWidth(), bitmap.getHeight());
        if (currentMaxEdge > maxEdge) {
            float ratio = maxEdge / (float) currentMaxEdge; // 精确缩放比例[6,8](@ref)
            Matrix matrix = new Matrix();
            matrix.postScale(ratio, ratio); // 等比缩放矩阵[3,6](@ref)
            Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
            bitmap.recycle(); // 释放原始Bitmap内存[4,5](@ref)
            bitmap = scaledBitmap;
        }

        return Bitmap2Bytes(bitmap);
    }

//    public static Bitmap smartCompress(String imagePath, int maxQuality) {
//        Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
//        if (bitmap == null) return null;
//
//        // 仅对最长边 > 1920 的图片进行尺寸压缩
//        int maxEdge = Math.max(bitmap.getWidth(), bitmap.getHeight());
//        if (maxEdge > 1920) {
//            // 尺寸压缩逻辑（略）
//        }
//
//        // 仅对 JPEG 且体积过大的图片进行质量压缩
//        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
//        bitmap.compress(Bitmap.CompressFormat.JPEG, maxQuality, outputStream);
//        byte[] compressedData = outputStream.toByteArray();
//
//        // 若压缩后体积反增，则放弃压缩
//        if (compressedData.length > getOriginalFileSize(imagePath)) {
//            return bitmap; // 返回未压缩的 Bitmap
//        }
//        return BitmapFactory.decodeByteArray(compressedData, 0, compressedData.length);
//    }

    public static byte[] processImage(String imagePath, int maxEdge) {
        // Step 1: 读取原始尺寸并计算inSampleSize
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(imagePath, options);

        int originalWidth = options.outWidth;
        int originalHeight = options.outHeight;

        int maxLength = Math.max(originalWidth, originalHeight);

        if (maxLength > 1920) {
            int rotation = getExifRotation(imagePath);
            // 交换宽高（若旋转90/270度）
            if (rotation % 180 != 0) {
                int temp = originalWidth;
                originalWidth = originalHeight;
                originalHeight = temp;
            }

            // 计算初步缩放比例
            float initialScale = Math.max(originalWidth, originalHeight) / (float) maxEdge;
            options.inSampleSize = (int) Math.floor(initialScale); // 向下取整，确保后续二次缩放必触发[3](@ref)

            // Step 2: 加载初步缩放后的Bitmap
            options.inJustDecodeBounds = false;
            options.inPreferredConfig = Bitmap.Config.ARGB_8888; // 避免质量损失[7](@ref)
            Bitmap rawBitmap = BitmapFactory.decodeFile(imagePath, options);

            // Step 3: 校正旋转方向
            Bitmap rotatedBitmap = rotateBitmap(rawBitmap, rotation);
            if (rawBitmap != rotatedBitmap) rawBitmap.recycle();

            // Step 4: 精确缩放至目标尺寸
            Bitmap finalBitmap = scaleToMaxEdge(rotatedBitmap, maxEdge);
            if (rotatedBitmap != finalBitmap) rotatedBitmap.recycle();

            ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
            finalBitmap.compress(Bitmap.CompressFormat.JPEG, 80, byteArrayStream); // 固定质量参数70

            // 2. 将压缩数据重新解码为Bitmap
            byte[] compressedBytes = byteArrayStream.toByteArray();

//            //质量压缩
//            Bitmap compressBitmap = compressToFixedQuality(finalBitmap);
//            if (finalBitmap != compressBitmap) finalBitmap.recycle();

//            return Bitmap2Bytes(compressBitmap);
            return compressedBytes;
        } else {
            int rotation = getExifRotation(imagePath);

            // Step 2: 加载初步缩放后的Bitmap
            options.inJustDecodeBounds = false;
            options.inPreferredConfig = Bitmap.Config.ARGB_8888; // 避免质量损失[7](@ref)
            Bitmap rawBitmap = BitmapFactory.decodeFile(imagePath, options);

            // Step 3: 校正旋转方向
            Bitmap rotatedBitmap = rotateBitmap(rawBitmap, rotation);
            if (rawBitmap != rotatedBitmap) rawBitmap.recycle();

//            Bitmap compressBitmap = compressToFixedQuality(rotatedBitmap);

            // 仅对 JPEG 且体积过大的图片进行质量压缩
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 80, outputStream);
            byte[] compressedData = outputStream.toByteArray();

            return compressedData;

        }
    }

    public static Bitmap compressToFixedQuality(Bitmap sourceBitmap) {
        if (sourceBitmap == null) return null;

        // 1. 质量压缩至70%
        ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
        sourceBitmap.compress(Bitmap.CompressFormat.JPEG, 70, byteArrayStream); // 固定质量参数70

        // 2. 将压缩数据重新解码为Bitmap
        byte[] compressedBytes = byteArrayStream.toByteArray();
        ByteArrayInputStream byteArrayInput = new ByteArrayInputStream(compressedBytes);
        Bitmap compressedBitmap = BitmapFactory.decodeStream(byteArrayInput);

        // 3. 资源回收与异常处理
        try {
            byteArrayStream.close();
            byteArrayInput.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return compressedBitmap;
    }

    public static Bitmap scaleToMaxEdge(Bitmap src, int maxEdge) {
        // 校正后的宽高（考虑旋转后的实际尺寸）
        int srcWidth = src.getWidth();
        int srcHeight = src.getHeight();
        int currentMaxEdge = Math.max(srcWidth, srcHeight);

        // 无需缩放的情况
        if (currentMaxEdge <= maxEdge) return src;

        // 计算精确缩放比例
        float scaleRatio = maxEdge / (float) currentMaxEdge;
        Matrix matrix = new Matrix();
        matrix.postScale(scaleRatio, scaleRatio);

        // 生成目标Bitmap（兼容特殊机型）
        Bitmap scaledBitmap = Bitmap.createBitmap(
                (int) (srcWidth * scaleRatio),
                (int) (srcHeight * scaleRatio),
                Bitmap.Config.ARGB_8888 // 保持高质量[7](@ref)
        );
        Canvas canvas = new Canvas(scaledBitmap);
        canvas.drawBitmap(src, matrix, new Paint(Paint.FILTER_BITMAP_FLAG)); // 抗锯齿处理[4](@ref)
        return scaledBitmap;
    }

    public static int getExifRotation(String imagePath) {
        int degree = 0;
        try {
            ExifInterface exif = new ExifInterface(imagePath);
            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    public static Bitmap rotateBitmap(Bitmap src, int degree) {
        if (degree == 0) return src;
        Matrix matrix = new Matrix();
        matrix.postRotate(degree);
        return Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true);
    }

    public static byte[] Bitmap2Bytes(Bitmap bm) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(CompressFormat.JPEG, 100, baos);
        return baos.toByteArray();
    }

    /**
     * 图片按比例大小压缩方法
     *
     * @param image （根据Bitmap图片压缩）
     * @return
     */
    public static Bitmap compressScale(Bitmap image) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(CompressFormat.JPEG, 100, baos);
        // 判断如果图片大于1M,进行压缩避免在生成图片（BitmapFactory.decodeStream）时溢出
        if (baos.toByteArray().length / 1024 > 1024) {
            baos.reset();// 重置baos即清空baos
            image.compress(CompressFormat.JPEG, 80, baos);// 这里压缩50%，把压缩后的数据存放到baos中
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        // 开始读入图片，此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        // 现在主流手机比较多是800*480分辨率，所以高和宽我们设置为
        // float hh = 800f;// 这里设置高度为800f
        // float ww = 480f;// 这里设置宽度为480f
        float hh = 512f;
        float ww = 512f;
        // 缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
        int be = 1;// be=1表示不缩放
        if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) { // 如果高度高的话根据高度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0)
            be = 1;
        newOpts.inSampleSize = be; // 设置缩放比例
        // newOpts.inPreferredConfig = Config.RGB_565;//降低图片从ARGB888到RGB565
        // 重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
        isBm = new ByteArrayInputStream(baos.toByteArray());
        bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩
        //return bitmap;
    }


    static Bitmap getScaledBitmap(String filePath, float maxWidth, float maxHeight) {

        Bitmap scaledBitmap = null;

        BitmapFactory.Options options = new BitmapFactory.Options();

        //by setting this field as true, the actual bitmap pixels are not loaded in the memory. Just the bounds are loaded. If
        //you try the use the bitmap here, you will get null.
        options.inJustDecodeBounds = true;
        Bitmap bmp = BitmapFactory.decodeFile(filePath, options);

        int actualHeight = options.outHeight;
        int actualWidth = options.outWidth;

        float imgRatio = (float) actualWidth / actualHeight;
        float maxRatio = maxWidth / maxHeight;

        //width and height values are set maintaining the aspect ratio of the image
        if (actualHeight > maxHeight || actualWidth > maxWidth) {
            if (imgRatio < maxRatio) {
                imgRatio = maxHeight / actualHeight;
                actualWidth = (int) (imgRatio * actualWidth);
                actualHeight = (int) maxHeight;
            } else if (imgRatio > maxRatio) {
                imgRatio = maxWidth / actualWidth;
                actualHeight = (int) (imgRatio * actualHeight);
                actualWidth = (int) maxWidth;
            } else {
                actualHeight = (int) maxHeight;
                actualWidth = (int) maxWidth;
            }
        }

        //setting inSampleSize value allows to load a scaled down version of the original image
        options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight);

        //inJustDecodeBounds set to false to load the actual bitmap
        options.inJustDecodeBounds = false;

        //this options allow android to claim the bitmap memory if it runs low on memory
        options.inPurgeable = true;
        options.inInputShareable = true;
        options.inTempStorage = new byte[16 * 1024];

        try {
            //load the bitmap from its path
            bmp = BitmapFactory.decodeFile(filePath, options);
        } catch (OutOfMemoryError exception) {
            exception.printStackTrace();
        }
        try {

            scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
        } catch (Exception exception) {
            exception.printStackTrace();
        }

        float ratioX = actualWidth / (float) options.outWidth;
        float ratioY = actualHeight / (float) options.outHeight;
        float middleX = actualWidth / 2.0f;
        float middleY = actualHeight / 2.0f;

        Matrix scaleMatrix = new Matrix();
        scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);

        Canvas canvas = new Canvas(scaledBitmap);
        canvas.setMatrix(scaleMatrix);
        canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));

        //check the rotation of the image and display it properly
        ExifInterface exif;
        try {
            exif = new ExifInterface(filePath);
            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
            Matrix matrix = new Matrix();
            if (orientation == 6) {
                matrix.postRotate(90);
            } else if (orientation == 3) {
                matrix.postRotate(180);
            } else if (orientation == 8) {
                matrix.postRotate(270);
            }
            scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
                    scaledBitmap.getWidth(), scaledBitmap.getHeight(),
                    matrix, true);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return scaledBitmap;
    }

    private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }

        final float totalPixels = width * height;
        final float totalReqPixelsCap = reqWidth * reqHeight * 2;

        while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
            inSampleSize++;
        }

        return inSampleSize;
    }

    static String getRealPathFromURI(Context context, Uri contentUri) {
        Cursor cursor = context.getContentResolver().query(contentUri, null, null, null, null);
        if (cursor == null) {
            return contentUri.getPath();
        } else {
            cursor.moveToFirst();
            int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
            String realPath = cursor.getString(index);
            cursor.close();
            return realPath;
        }
    }

    public boolean isPath(Context context, Uri contentUri) {
        Cursor cursor = context.getContentResolver().query(contentUri, null, null, null, null);
        if (cursor == null) {
            return false;
        } else {
            cursor.close();
            return true;
        }
    }


    /**
     * 将Bitmap转成二进制
     *
     * @param bitmap
     * @return
     */
    public static byte[] getBitmapByte(Bitmap bitmap) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        bitmap.compress(CompressFormat.JPEG, 100, out);
        try {
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return out.toByteArray();
    }

    /**
     * 保存图片到sd卡
     *
     * @param bmp
     * @param filename
     * @return
     */
    public static boolean saveBitmap2file(Bitmap bmp, String filename) {
        CompressFormat format = CompressFormat.JPEG;
        int quality = 100;
        OutputStream stream = null;
        try {
            stream = new FileOutputStream(filename);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        return bmp.compress(format, quality, stream);
    }

    /**
     * 从SD卡里面读取图片
     *
     * @param path 图片的完整路径，包含文件名
     * @return Bitmap
     * @since v 1.0
     */
    public static Bitmap getBitmapBySD(String path, String fileName) {
        Bitmap b = null;
        try {
            File f = null;
            if (fileName != null)
                f = new File(path, fileName);
            else
                f = new File(path);
            // Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;

            FileInputStream fis = new FileInputStream(f);
            BitmapFactory.decodeStream(fis, null, o);
            fis.close();

            int scale = 1;
            int IMAGE_MAX_SIZE = 200;
            if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
                scale = (int) Math.pow(
                        2,
                        (int) Math.round(Math.log(IMAGE_MAX_SIZE
                                / (double) Math.max(o.outHeight, o.outWidth))
                                / Math.log(0.5)));
            }

            // Decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            fis = new FileInputStream(f);
            b = BitmapFactory.decodeStream(fis, null, o2);
            fis.close();
        } catch (Exception e) {
        }
        return b;
    }

    /**
     * 保存成本地图片
     *
     * @param picUrl
     * @param name
     */
    public static void savePictureFromNet(final String picUrl, final String name) {
        new Thread() {
            @Override
            public void run() {
                super.run();
                try {
                    File dir = new File(name);
                    if (!dir.exists()) {// Launch camera to take photo for
                        dir.mkdirs();// 创建照片的存储目录
                    }
                    URL url = new URL(picUrl);
                    HttpURLConnection conn = (HttpURLConnection) url
                            .openConnection();
                    conn.setConnectTimeout(5000);
                    // 获取到文件的大小
                    InputStream is = conn.getInputStream();
                    File file = new File(name);
                    FileOutputStream fos = new FileOutputStream(file);
                    BufferedInputStream bis = new BufferedInputStream(is);
                    byte[] buffer = new byte[1024];
                    int len;
                    // int total = 0;
                    while ((len = bis.read(buffer)) != -1) {
                        fos.write(buffer, 0, len);
                        // total += len;
                    }
                    fos.close();
                    bis.close();
                    is.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }

    /**
     * 将图片的网络地址转化为唯一的文件名
     *
     * @param url
     * @return
     */
    public static String urlToUuid(String url) {
        return UUID.nameUUIDFromBytes(url.getBytes()).toString();
    }


    public static Bitmap imageoperation(Bitmap mbitmap, float saturation) {
        //传入的Bitmap默认不可修改，需要创建新的Bitmap
        Bitmap mbitmap_fu = Bitmap.createBitmap(mbitmap.getWidth(), mbitmap.getHeight(), Bitmap.Config.ARGB_8888);
        //创建画布，在新的bitmap上绘制
        Canvas canvas = new Canvas(mbitmap_fu);
        //设置画笔抗锯齿，后面在Bitmap上绘制需要使用到画笔
        Paint mpaint = new Paint(Paint.ANTI_ALIAS_FLAG);
//        mpaint.setColor(Color.WHITE);
//        mpaint.setStyle(Paint.Style.FILL);
//        mpaint.setShader(new BitmapShader(mbitmap_fu, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
        ColorMatrix saturationmatrix = new ColorMatrix();
        saturationmatrix.setSaturation(saturation);

        mpaint.setColorFilter(new ColorMatrixColorFilter(saturationmatrix));

        canvas.drawBitmap(mbitmap, 0, 0, mpaint);
//        canvas.drawCircle(mbitmap.getWidth() / 2, mbitmap.getHeight() / 2, mbitmap.getHeight() / 2, mpaint);
//        canvas.drawRect(0, 0, mbitmap.getWidth(), mbitmap.getWidth(), mpaint);
        return mbitmap_fu;
    }


    /**
     * 自适应图片
     *
     * @param context
     * @param image
     * @param bitmap
     */
    public static void setImageViewMathParent(Activity context,
                                              ImageView image, Bitmap bitmap) {
        //获得屏幕密度
        DisplayMetrics displayMetrics = new DisplayMetrics();
        context.getWindowManager().getDefaultDisplay()
                .getMetrics(displayMetrics);
        //获得屏幕宽度和图片宽度的比例
        float scalew = (float) displayMetrics.widthPixels
                / (float) bitmap.getWidth();
        //获得ImageView的参数类
        ViewGroup.LayoutParams vgl = image.getLayoutParams();
        //设置ImageView的宽度为屏幕的宽度
        vgl.width = displayMetrics.widthPixels;
        //设置ImageView的高度
        vgl.height = (int) (bitmap.getHeight() * scalew);
        //设置图片充满ImageView控件
        image.setScaleType(ImageView.ScaleType.FIT_XY);
        //等比例缩放
        image.setAdjustViewBounds(true);
        image.setLayoutParams(vgl);
        image.setImageBitmap(bitmap);

        if (bitmap != null && bitmap.isRecycled()) {
            bitmap.recycle();
        }
    }


    public static Bitmap ImageCompress(Bitmap bitmap) {
        // 图片允许最大空间 单位：KB
        double maxSize = 32.00;
        // 将bitmap放至数组中，意在bitmap的大小（与实际读取的原文件要大）
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(CompressFormat.JPEG, 100, baos);
        byte[] b = baos.toByteArray();
        // 将字节换成KB
        double mid = b.length / 1024;
        // 判断bitmap占用空间是否大于允许最大空间 如果大于则压缩 小于则不压缩
        if (mid > maxSize) {
            // 获取bitmap大小 是允许最大大小的多少倍
            double i = mid / maxSize;
            // 开始压缩 此处用到平方根 将宽带和高度压缩掉对应的平方根倍
            bitmap = zoomImage(bitmap, bitmap.getWidth() / Math.sqrt(i),
                    bitmap.getHeight() / Math.sqrt(i));
        }
        return bitmap;
    }

    public static Bitmap zoomImage(Bitmap bgimage, double newWidth, double newHeight) {
        // 获取这个图片的宽和高
        float width = bgimage.getWidth();
        float height = bgimage.getHeight();
        // 创建操作图片用的matrix对象
        Matrix matrix = new Matrix();
        // 计算宽高缩放率
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // 缩放图片动作
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap bitmap = Bitmap.createBitmap(bgimage, 0, 0, (int) width,
                (int) height, matrix, true);
        return bitmap;
    }


    public static Uri bitmap2uri(Context c, Bitmap b) {
        File path = new File(c.getCacheDir() + File.separator + System.currentTimeMillis() + ".jpg");
        try {
            OutputStream os = new FileOutputStream(path);
            b.compress(CompressFormat.JPEG, 100, os);
            os.close();
            return Uri.fromFile(path);
        } catch (Exception ignored) {
        }
        return null;
    }


    /**
     * 临时保存
     *
     * @param c
     * @param bitmap
     * @return
     */
    public static String bitmap2fileTem(Context c, Bitmap bitmap) {
        if (bitmap != null) {
            File currentFile = new File(c.getCacheDir() + File.separator + System.currentTimeMillis() + ".jpg");

            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            bitmap.compress(CompressFormat.PNG, 100, stream);
            FileOutputStream fos = null;
            BufferedOutputStream bos = null;
            BufferedInputStream bis = null;
            File imageFile = null;
            try {
                bis = new BufferedInputStream(new ByteArrayInputStream(
                        stream.toByteArray()));
                imageFile = currentFile;
                fos = new FileOutputStream(imageFile);
                bos = new BufferedOutputStream(fos);
                byte[] b = new byte[1024];
                int length;
                while ((length = bis.read(b)) != -1) {
                    bos.write(b, 0, length);
                    bos.flush();
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (bis != null) {
                        bis.close();
                    }
                    if (bos != null) {
                        bos.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            c.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
                    Uri.fromFile(new File(currentFile.getPath()))));
            return currentFile.getPath();
        }
        return "";
    }


    public static String bitmap2file(Context c, Bitmap bitmap) {
        if (bitmap != null) {
            File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsoluteFile();
            File appDir = new File(file, "scyeguan");
            boolean createed = false;
            if (!appDir.exists()) {
                createed = appDir.mkdirs();
            }
            String fileName = System.currentTimeMillis() + ".png";
            File currentFile = new File(appDir, fileName);

            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            bitmap.compress(CompressFormat.PNG, 100, stream);
            FileOutputStream fos = null;
            BufferedOutputStream bos = null;
            BufferedInputStream bis = null;
            File imageFile = null;
            try {
                bis = new BufferedInputStream(new ByteArrayInputStream(
                        stream.toByteArray()));
                imageFile = currentFile;
                fos = new FileOutputStream(imageFile);
                bos = new BufferedOutputStream(fos);
                byte[] b = new byte[1024];
                int length;
                while ((length = bis.read(b)) != -1) {
                    bos.write(b, 0, length);
                    bos.flush();
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (bis != null) {
                        bis.close();
                    }
                    if (bos != null) {
                        bos.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            c.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
                    Uri.fromFile(new File(currentFile.getPath()))));
            return currentFile.getPath();
        }
        return "";
    }


    /**
     * View 转bitmap
     *
     * @param v
     * @return
     */
    public static Bitmap loadBitmapFromView(View v) {
        v.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
        v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
        v.setDrawingCacheEnabled(true);
        Bitmap shareBitmap = Bitmap.createBitmap(v.getDrawingCache());
        v.setDrawingCacheEnabled(false);

        return shareBitmap;
    }

    /**
     * 将控件v 生成bitmap
     *
     * @param v
     * @return
     */
    public static Bitmap loadBitmapFromView1(View v) {
        int w = v.getWidth();
        int h = v.getHeight();
        if (w <= 0 || h <= 0) {
            return null;
        }
        Bitmap bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bmp);

        v.draw(c);

        return bmp;
    }

    //加载图片
    public static Bitmap getURLimage(String url) {
        Bitmap bmp = null;
        try {
            URL myurl = new URL(url);
            // 获得连接
            HttpURLConnection conn = (HttpURLConnection) myurl.openConnection();
            conn.setConnectTimeout(6000);//设置超时
            conn.setDoInput(true);
            conn.setUseCaches(true);//不缓存
            conn.connect();
            InputStream is = conn.getInputStream();//获得图片的数据流
            bmp = BitmapFactory.decodeStream(is);
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bmp;
    }
}